package com.datn.utils.places;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.text.Html;
import android.widget.Toast;

import com.datn.utils.DecodePolyline;
import com.google.android.maps.GeoPoint;

public class JsonDirection {
	
	private GeoPoint startPosition;
	private GeoPoint endPosition;
	
	public static final String TYPE_RETURN="json";
	public static final String LANGUAGE="en";
	
	public Context mContext;
	
	public JsonDirection(Context context, GeoPoint start, GeoPoint end) {
		// TODO Auto-generated constructor stub
		this.startPosition=start;
		this.endPosition=end;
		mContext = context;
	}
	
	


	private String getURL(){		
		//http://maps.googleapis.com/maps/api/directions/json?origin=16.065444,108.183231&waypoints=16.071383,108.191321&sensor=false
		//http://maps.googleapis.com/maps/api/directions/json?origin=52.31,16.71&destination=51.27,6.75&sensor=false
		StringBuilder urlString = new StringBuilder(); 
		urlString.append("http://maps.googleapis.com/maps/api/directions/"+TYPE_RETURN); 
		urlString.append("?origin="+(startPosition.getLatitudeE6()/1E6)+","+(startPosition.getLongitudeE6()/1E6));//from 
		urlString.append("&destination="+(endPosition.getLatitudeE6()/1E6)+","+(endPosition.getLongitudeE6()/1E6)); //to
		urlString.append("&sensor=false&language="+LANGUAGE);
		return urlString.toString();
	}
	
	
	
	
	private static String getResponseFromUrl(URL url) 
	{
		try {
			URLConnection urlConnection = url.openConnection();
			BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
			StringBuilder strBuilder = new StringBuilder();
			String temp;
			while ((temp = in.readLine()) != null) {
				strBuilder.append(temp);
			}
			return strBuilder.toString();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} 
		return null;
	}
	
	
	
	
	public DirectionObject getDirectionFromJSON(){
		
		DirectionObject directionObject=new DirectionObject();
		URL urlJson;
		try {
			urlJson = new URL(getURL());

			String jsonResponse = getResponseFromUrl(urlJson);

			if (jsonResponse != null) 
			{
				if (jsonResponse.contains("while(1);")) 
				{
					jsonResponse = jsonResponse.replace("while(1);", "");
				}

				
				JSONObject jsonObject = new JSONObject(jsonResponse);
				
				//Process JSON HERE
				JSONArray jsonRoutes=jsonObject.getJSONArray("routes");				
					JSONObject route = jsonRoutes.getJSONObject(0);
						JSONArray legs=this.getJSONArrayFromJSONObject(route, "legs");//route.getJSONArray("legs");
						JSONObject leg= legs.getJSONObject(0);
							JSONObject distance=this.getJSONObjectFromJSONObject(leg, "distance");//leg.getJSONObject("distance");
							JSONObject duration=this.getJSONObjectFromJSONObject(leg, "duration");//leg.getJSONObject("duration");
							JSONObject start_location=this.getJSONObjectFromJSONObject(leg, "start_location");//leg.getJSONObject("start_location");
							JSONObject end_location=this.getJSONObjectFromJSONObject(leg, "end_location");//leg.getJSONObject("end_location");
							String stStartAddress=this.getStringFromJSONObject(leg, "start_address");//leg.getString("start_address");
							String stEndAddress=this.getStringFromJSONObject(leg, "end_address");//leg.getString("end_address");
								JSONArray steps=this.getJSONArrayFromJSONObject(leg, "steps");
								if (steps!=null){
									for (int i = 0; i < steps.length(); i++) {
										JSONObject step = (JSONObject) steps.get(i);
										
										JSONObject distanceStep = this.getJSONObjectFromJSONObject(step, "distance");
											directionObject.addElementToTextDistance(this.getStringFromJSONObject(distanceStep, "text"));//Distance
											//directionObject.addElementToValueDistance(this.getIntFromJSONObject(distanceStep, "value"));
										JSONObject durationStep = this.getJSONObjectFromJSONObject(step, "duration");
											directionObject.addElementToDuration(this.getStringFromJSONObject(durationStep, "text"));
											
											
										JSONObject end_locationStep = this.getJSONObjectFromJSONObject(step, "end_location");
											directionObject.addElementToEndLocation(this.getDoubleFromJSONObject(end_locationStep, "lat"), this.getDoubleFromJSONObject(end_locationStep, "lng"));
											
											
										String html_instructionsStep = this.getStringFromJSONObject(step, "html_instructions");
											directionObject.addElementToInstructions("Step ["+i+"]:"+Html.fromHtml(html_instructionsStep).toString());
											
											
										JSONObject polylineStep = this.getJSONObjectFromJSONObject(step, "polyline");
										
										
										JSONObject start_locationStep = this.getJSONObjectFromJSONObject(step, "start_location");
											directionObject.addElementToStartLocation(this.getDoubleFromJSONObject(start_locationStep, "lat"), this.getDoubleFromJSONObject(start_locationStep, "lng"));
	
									}
								
								}
								
						try {
							JSONObject overviewPolyline=route.getJSONObject("overview_polyline");
							String stOverviewPolyline = overviewPolyline.getString("points");
							directionObject.setPolyline(DecodePolyline.decode(stOverviewPolyline));
						} catch (Exception e) {
							// TODO: handle exception
							directionObject.setPolyline(new ArrayList<GeoPoint>());
						}
						
			}



		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			Toast.makeText(mContext, "Cannot parse JSON result", Toast.LENGTH_LONG).show();			
			return null;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			Toast.makeText(mContext, "Cannot parse JSON result", Toast.LENGTH_LONG).show();
			return null;
		}
		
		return directionObject;
	}
	
	
	
	public double getDoubleFromJSONObject(JSONObject json, String stLabel){
		try {
			return json.getDouble(stLabel);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return -1;
	}
	
	public JSONObject getJSONObjectFromJSONObject(JSONObject json, String stLabel){
		try {
			return json.getJSONObject(stLabel);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return null;
	}
	
	public JSONArray getJSONArrayFromJSONObject(JSONObject json, String stLabel){
		try {
			return json.getJSONArray(stLabel);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return null;
	}
	
	
	public String getStringFromJSONObject(JSONObject json, String stLabel){
		try {
			return json.getString(stLabel);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return "";
	}
	
	public int getIntFromJSONObject(JSONObject json, String stLabel){
		try {
			return json.getInt(stLabel);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return -1;
	}
	
	
	
	
}
